package com.ard.camera.demos;

import com.ard.camera.demos.config.HostMonitorConfig;
import com.ard.camera.demos.entry.DvrHostEntry;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.io.IOException;
import java.net.InetAddress;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Component
@Slf4j
public class DvrHostPingChecker {

    @Autowired
    private HostMonitorConfig config;

    @Autowired
    private DvrHostFileReader dvrHostFileReader;

    /**
     * 获取所有硬盘录像机的主机配置
     */
    public Map<String, List<DvrHostEntry>> getAllDvrHosts() {
        return dvrHostFileReader.readAllDvrHosts();
    }

    /**
     * 检查主机是否可达
     */
    public boolean isHostReachable(String host, int timeout) {
        try {
            InetAddress inetAddress = InetAddress.getByName(host);
            return inetAddress.isReachable(timeout);
        } catch (IOException e) {
            log.debug("Ping主机失败: {} - {}", host, e.getMessage());
            return false;
        }
    }

    /**
     * 带重试的主机检查（针对特定硬盘录像机）
     */
    public DvrHostCheckResult checkDvrHostWithRetry(DvrHostEntry dvrHostEntry) {
        String host = dvrHostEntry.getHostAddress();
        int retryCount = config.getRetryCount();
        int timeout = config.getTimeout();

        for (int i = 1; i <= retryCount; i++) {
            try {
                boolean reachable = isHostReachable(host, timeout);
                if (reachable) {
                    log.debug("硬盘录像机 {} 的主机 {} 第 {} 次尝试成功",
                            dvrHostEntry.getDvrIp(), host, i);
                    return new DvrHostCheckResult(dvrHostEntry, true, i);
                } else {
                    log.debug("硬盘录像机 {} 的主机 {} 第 {} 次尝试失败",
                            dvrHostEntry.getDvrIp(), host, i);
                    if (i < retryCount) {
                        Thread.sleep(5000); // 重试间隔1秒
                    }
                }
            } catch (Exception e) {
                log.debug("硬盘录像机 {} 的主机 {} 第 {} 次尝试异常: {}",
                        dvrHostEntry.getDvrIp(), host, i, e.getMessage());
                if (i < retryCount) {
                    try {
                        Thread.sleep(5000);
                    } catch (InterruptedException ie) {
                        Thread.currentThread().interrupt();
                    }
                }
            }
        }

        return new DvrHostCheckResult(dvrHostEntry, false, retryCount);
    }

    /**
     * 检查单个硬盘录像机的所有主机
     */
    public List<DvrHostCheckResult> checkDvrHosts(String dvrIp) {
        Map<String, List<DvrHostEntry>> allDvrHosts = getAllDvrHosts();
        List<DvrHostEntry> dvrHosts = allDvrHosts.get(dvrIp);

        if (dvrHosts == null || dvrHosts.isEmpty()) {
            log.warn("硬盘录像机 {} 没有配置监控主机", dvrIp);
            return new ArrayList<>();
        }

        List<DvrHostCheckResult> results = new ArrayList<>();
        for (DvrHostEntry dvrHostEntry : dvrHosts) {
            try {
                DvrHostCheckResult result = checkDvrHostWithRetry(dvrHostEntry);
                results.add(result);

                log.info("硬盘录像机 {} - 主机检查: {} ({}) - {}",
                        dvrIp, dvrHostEntry.getHostName(), dvrHostEntry.getHostAddress(),
                        result.isReachable() ? "正常" : "失败");

            } catch (Exception e) {
                log.error("检查硬盘录像机 {} 的主机时发生错误: {}", dvrIp, dvrHostEntry, e);
                results.add(new DvrHostCheckResult(dvrHostEntry, false, 0, e.getMessage()));
            }
        }

        return results;
    }

    /**
     * 检查所有硬盘录像机的所有主机
     */
    public Map<String, List<DvrHostCheckResult>> checkAllDvrHosts() {
        Map<String, List<DvrHostEntry>> allDvrHosts = getAllDvrHosts();
        Map<String, List<DvrHostCheckResult>> allResults = new HashMap<>();

        if (allDvrHosts.isEmpty()) {
            log.warn("没有配置任何硬盘录像机");
            return allResults;
        }

        for (Map.Entry<String, List<DvrHostEntry>> entry : allDvrHosts.entrySet()) {
            String dvrIp = entry.getKey();
            List<DvrHostCheckResult> dvrResults = checkDvrHosts(dvrIp);
            allResults.put(dvrIp, dvrResults);
        }

        return allResults;
    }

    @Data
    @AllArgsConstructor
    public static class DvrHostCheckResult {
        private DvrHostEntry dvrHostEntry;
        private boolean reachable;
        private int attempts; // 尝试次数
        private String errorMessage;

        public DvrHostCheckResult(DvrHostEntry dvrHostEntry, boolean reachable, int attempts) {
            this(dvrHostEntry, reachable, attempts, null);
        }

        /**
         * 获取完整显示信息
         */
        public String getDisplayInfo() {
            return String.format("硬盘录像机: %s, 主机: %s (%s)",
                    dvrHostEntry.getDvrIp(),
                    dvrHostEntry.getHostName(),
                    dvrHostEntry.getHostAddress());
        }

        @Override
        public String toString() {
            String status = reachable ? "正常" : "失败";
            return String.format("%s - %s (尝试次数: %d)",
                    getDisplayInfo(), status, attempts);
        }
    }
}